%{
/*
 * ctoolscan.l: the flex description file for the ebctool scanner.
 * Clunix, cezanne@clunix.com, 2006.7
 *
 * Copyright (c) 2001-2006 by Clunix Inc. All Rights Reserved.
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define MAX_STR_CONST	1024
#define MAX_BUF		1024

#include "ebctool.h"

#ifdef ECM_DEBUG
#include "ctoolparser_dbg.h"
#else
#include "ctoolparser_nodbg.h"
#endif

void cterror(char *);

/* Support for the readline and history libraries.  This allows
 * nicer input on the interactive part of input.
 */

/* Have input call the following function. */
#undef  YY_INPUT
#define YY_INPUT(buf,result,max_size) \
		ebctool_readline((char *)buf, &result, max_size)
#define YY_NO_INPUT

%}

%option nounput
%option yylineno
%option noyyalloc noyyrealloc noyyfree

%x sc_arg
%x sc_str
%x sc_error
#DEBUG START
%x sc_pch_arg
#DEBUG END

%%
	char	buf[MAX_BUF];
	char	*buf_ptr = buf;

<<EOF>>		return ENDOFBUF;

#[^\n]*\n	

quit		BEGIN(sc_arg); return Quit;
help		BEGIN(sc_arg); return Help;
connect		BEGIN(sc_arg); return Connect;
peercon		BEGIN(sc_arg); return PeerCon;
call		BEGIN(sc_arg); return Call;
call1		BEGIN(sc_arg); return Call1;
bcall		BEGIN(sc_arg); return BCall;
tcall		BEGIN(sc_arg); return TCall;
send		BEGIN(sc_arg); return Send;
recv		BEGIN(sc_arg); return Recv;
bsend		BEGIN(sc_arg); return BSend;
brecv		BEGIN(sc_arg); return BRecv;
peerbsend	BEGIN(sc_arg); return PeerBSend;
peerbrecv	BEGIN(sc_arg); return PeerBRecv;
route		BEGIN(sc_arg); return Route;
echo_server	BEGIN(sc_arg); return EchoServer;
#DEBUG START
moncb		BEGIN(sc_arg); return MonCb;
pch		BEGIN(sc_pch_arg); return PCH;
pktb		BEGIN(sc_arg); return PKTB;
callinfo	BEGIN(sc_arg); return CallInfo;
monitor		BEGIN(sc_arg); return Monitor;
mtrace		BEGIN(sc_arg); return MTrace;
#DEBUG END

[\n[:blank:]]
[^\n[:blank:]]+	{
			ctlval.s_value = ecm_strdup(yytext);
			BEGIN(sc_error);
			return ErrorCmd;
		}

<sc_error>{
[^\n]+
\n	BEGIN(INITIAL);
}

<sc_arg>{
[[:blank:]]
\\\n	{
		continuation = ECM_TRUE;
	}

^#[^\n]*\n

[^\n\\[:blank:]\"]+	{
			ctlval.s_value = ecm_strdup(yytext);
			return Literal;
		}

\"		buf_ptr = buf; BEGIN(sc_str);
\n		BEGIN(INITIAL); continuation = ECM_FALSE; return ENDOFCMD;

.		return Error;
}

<sc_str>{
[\n[:blank:]]+	ecm_strcpy(buf_ptr, yytext); buf_ptr += yyleng;
\"		{
			BEGIN(sc_arg);
			*buf_ptr = '\0';
			ctlval.s_value = ecm_strdup(buf);
			return String;
		}

\\[0-7]{1,3} {
		/* octal escape sequence */
		int	result;
		ecm_sscanf(yytext + 1, "%o", &result);
		if (result > 0xff)
				;
		*buf_ptr++ = result;
		}

\\[0-9]+	{
			/* generate error */
		}

\\n	*buf_ptr++ = '\n';
\\t	*buf_ptr++ = '\t';
\\r	*buf_ptr++ = '\r';
\\b	*buf_ptr++ = '\b';
\\f	*buf_ptr++ = '\f';
\\\\	*buf_ptr++ = '\\';
\\\"	*buf_ptr++ = '"';	/* " */
\\[ ]	*buf_ptr++ = ' ';
\\(.|\n)	

[^\\\n[:blank:]\"]+	{
		char	*yptr = yytext;
		while (*yptr)
			*buf_ptr++ = *yptr++;
		}
}

#DEBUG START

<sc_pch_arg>{
[[:blank:]]
info	BEGIN(sc_arg); return PCH_Info;
list	return PCH_List;
\n	BEGIN(INITIAL); return ENDOFCMD;
.	BEGIN(INITIAL); return Error;
}

#DEBUG END

%%

void
et2error(char *msg)
{
}

void *
yyalloc(yy_size_t bytes)
{
	return ecm_malloc(bytes);
}

void *
yyrealloc(void *ptr, yy_size_t bytes)
{
	return ecm_realloc(ptr, bytes);
}

void
yyfree(void *ptr)
{
	ecm_free(ptr);
}
